package serverActualizaciones;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import util.SocketManager;

public class SesionActualizaciones implements Runnable {

	private final String RUTA = "act_files/config_srv.doc";
	private final String LOGINFILE = "act_files/login_act";
	private final int TAMANYOBUFFER = 1024;
	
	private SocketManager sm;
	private boolean loggedIn;
	
	public SesionActualizaciones(SocketManager sm) {
		this.sm = sm;
		loggedIn = false;
	}
	
	@Override
	public void run() {
		try {
			ejecucion();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void ejecucion() throws IOException {
		System.out.println("Sesion iniciada");
		String usuario = null;
		boolean salir = false;
		while (!salir) {
			//Recibe el comando solicitado
			StringTokenizer st = new StringTokenizer(sm.leer(), " ");
			String comando = st.nextToken();
			System.out.println("Comando recibido: "+ comando);
			if (comando.equals("GET_FICHERO")) {
				if (loggedIn) {
					System.out.println("Actualización iniciada");
					//coge el archivo a mandar
					FileInputStream origen = new FileInputStream(RUTA);
					byte[] buffer = new byte[TAMANYOBUFFER];
					int len;
					//Va enviando los bytes del fichero
					while((len=origen.read(buffer)) > 0) {
						//Espera confirmación del cliente de que está preparado para recibir 
						sm.leer();
						//Avisa al cliente de que le va a mandar bytes
						sm.escribir("BYTES");
						//Espera confirmación del cliente de que está preparado para recibir los bytes
						sm.leer();
						//Envía los bytes
						sm.escribir(buffer, len);
					}
					origen.close();
					//Espera confirmación del cliente de que está preparado para recibir 
					sm.leer();
					//Avisa de que ya se ha acabado de mandar el archivo
					sm.escribir("FIN");
					System.out.println("Actualización finalizada");
				} else sm.escribir("701 ERR El usuario debe haber iniciado sesion");
			} else if (comando.equals("USER")) {
				if (!st.hasMoreTokens()) sm.escribir("411 ERR Falta el nombre de usuario.");
				else {
					usuario = st.nextToken();
					sm.escribir("211 OK Bienvenido " + usuario + ".");
				}
			} else if (comando.equals("PASS")) {
				if (usuario == null) sm.escribir("700 ERR No se ha introducido un usuario previo");
				else {
					if (!st.hasMoreTokens()) sm.escribir("413 ERR Falta la clave.");
					else {
						String pass = st.nextToken();
						System.out.println(pass);
						sm.escribir(login(usuario,pass));
					}
				}
			} else if (comando.equals("SALIR")) {
				salir = true;
				loggedIn = false;
				sm.escribir("218 OK Adios.");
			} else {
				sm.escribir("999 ERR No se ha reconocido el comando");
				System.out.println("Comando desconocido");
			}
		}
		sm.cerrarSocket();
	}

	/**
	 * Metodo para comprobar si los datos de login son correctos e inciar sesión en caso de que asi sea.
	 * Recorre un fichero con los diferentes usuarios y contraseñas en busca del usuario y contraseña dado
	 * 
	 * @param usuario Usuario que quiere iniciar sesion
	 * @param pass Contraseña del usuario
	 * @return String con el mensaje a mandar por el socket
	 */
	private String login(String usuario, String pass) {
        File file = new File(LOGINFILE);
        FileInputStream fileInputStream;
        try {
			fileInputStream = new FileInputStream(file);
			InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String line = null;
			do {
				line = bufferedReader.readLine();
				if (line != null) {
					StringTokenizer st = new StringTokenizer(line, ";");
					if (usuario.equals(st.nextToken())) if (pass.equals(st.nextToken())) {
						//no lo hago con un AND para asegurarme que el orden de ejecución es el correcto
						fileInputStream.close();
						loggedIn = true;
						return "212 OK Bienvenido al sistema.";
					}
				}
			} while (line != null);
			return "412 ERR La clave es incorrecta.";
		} catch (Exception e) {
		        e.printStackTrace();
		        throw new RuntimeException("Unexpected error, check the StackTrace");
		}
	}
}
